package com.ml.mall.service.shopping.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ml.mall.bean.req.CouponListCheckReq;
import com.ml.mall.bean.req.ProductCartReq;
import com.ml.mall.bean.res.ShoppingCartQueryRes;
import com.ml.mall.bean.res.company.CompanyInfoRes;
import com.ml.mall.bean.res.coupon.CouponProductRes;
import com.ml.mall.bean.res.coupon.CouponSupplierRes;
import com.ml.mall.bean.res.product.SysProductShopPageRes;
import com.ml.mall.bean.res.variant.SysProductVariantQueryCartRes;
import com.ml.mall.bean.res.vo.SupplierOrderVO;
import com.ml.mall.bean.res.vo.VariantVO;
import com.ml.mall.consts.CommonConsts;
import com.ml.mall.consts.CommonConsts;
import com.ml.mall.entity.company.SysCompany;
import com.ml.mall.entity.coupon.SysCoupon;
import com.ml.mall.entity.deduct.SysADeduct;
import com.ml.mall.entity.sys.SysUser;
import com.ml.mall.entity.variant.SysProductVariant;
import com.ml.mall.entity.variant.SysProductVariantSales;
import com.ml.mall.entity.variant.SysProductVariantSku;
import com.ml.mall.mapper.coupon.SysCouponMapper;
import com.ml.mall.mapper.coupon.SysCouponProductRelationMapper;
import com.ml.mall.mapper.coupon.SysCouponSupplierRelationMapper;
import com.ml.mall.mapper.coupon.SysCouponSupplierUnuseProductMapper;
import com.ml.mall.security.JwtUtil;
import com.ml.mall.service.company.SysCompanyLogisticsInfoService;
import com.ml.mall.service.company.SysCompanyService;
import com.ml.mall.service.coupon.SysCouponService;
import com.ml.mall.service.credit.SysCreditService;
import com.ml.mall.service.deduct.SysADeductService;
import com.ml.mall.service.shopping.SysShoppingCartService;
import com.ml.mall.service.tax.TaxService;
import com.ml.mall.service.variant.SysProductVariantPicService;
import com.ml.mall.service.variant.SysProductVariantSalesService;
import com.ml.mall.service.variant.SysProductVariantService;
import com.ml.mall.service.variant.SysProductVariantSkuService;
import com.ml.mall.utils.NumberUtils;
import com.ml.mall.utils.OrderPriceUtils;
import com.ml.mall.utils.RedisUtil;
import com.ml.mall.utils.ShoppingCartUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * Created by kyyang on 2021/2/28 13:48
 */
@Service
@Slf4j
public class SysShoppingCartServiceImpl implements SysShoppingCartService {

    @Autowired
    private RedisUtil redisUtil;

    @Autowired
    private SysProductVariantService sysProductVariantService;

    @Autowired
    private SysProductVariantPicService sysProductVariantPicService;

    @Autowired
    private SysProductVariantSkuService sysProductVariantSkuService;

    @Autowired
    private SysProductVariantSalesService sysProductVariantSalesService;

    @Autowired
    private TaxService taxService;

    @Autowired
    private SysADeductService sysADeductService;

    @Autowired
    private SysCompanyService sysCompanyService;

    @Autowired
    private SysCompanyLogisticsInfoService sysCompanyLogisticsInfoService;

    @Autowired
    private SysCreditService sysCreditService;


    @Override
    public void addProduct2Cart(List<ProductCartReq> productCartReq) {
        String cartKey = ShoppingCartUtils.getCurShoppingCartKey();
        Map value = (Map) redisUtil.get(cartKey);
        Map<String,Integer> map = new HashMap<>();
        if(MapUtils.isNotEmpty(value)){
            map = value;
        }
        if(null != productCartReq && productCartReq.size()>0){
            for (ProductCartReq cartReq : productCartReq) {
                map.put(cartReq.getVariantId()+"",cartReq.getQuantity());
            }
        }
        redisUtil.set(cartKey,map);
    }

    @Override
    public void delProduct2Cart(ProductCartReq productCartReq) {
        String cartKey = ShoppingCartUtils.getCurShoppingCartKey();
        Map value = (Map) redisUtil.get(cartKey);
        Map<String,Integer> map = new HashMap<>();
        if(MapUtils.isNotEmpty(value)){
            map = value;
        }
        if(map.containsKey(productCartReq.getVariantId().toString())){
            map.remove(productCartReq.getVariantId().toString());
            redisUtil.set(cartKey,map);
        }else {
            log.warn("当前用户购物车:[{}] 商品不存在",productCartReq.getVariantId());
        }
    }

    @Override
    public void clearCart() {
        String cartKey = ShoppingCartUtils.getCurShoppingCartKey();
        Map value = (Map) redisUtil.get(cartKey);
        Map<String,Integer> map = new HashMap<>();
        if(MapUtils.isNotEmpty(value)){
            map = value;
        }
        map.clear();
        redisUtil.set( cartKey, map );
    }

    @Override
    public void modifyProduct2Cart(ProductCartReq productCartReq) {

        String cartKey = ShoppingCartUtils.getCurShoppingCartKey();
        Map value = (Map) redisUtil.get(cartKey);
        Map<String,Integer> map = new HashMap<>();
        if(MapUtils.isNotEmpty(value)){
            map = value;
        }
        if(productCartReq.getQuantity()== 0){
            map.remove(productCartReq.getVariantId());
        }else{
            map.put(String.valueOf(productCartReq.getVariantId()),productCartReq.getQuantity());
        }
        log.info("productCartReq====={}",cartKey);
        log.info("map====={}",map);
        redisUtil.set(cartKey,map);
    }

    @Override
    public ShoppingCartQueryRes queryProduct2Cart() {
        String cartKey = ShoppingCartUtils.getCurShoppingCartKey();
        Map value = (Map) redisUtil.get(cartKey);
        Map<String,Integer> map;
        ShoppingCartQueryRes res = new ShoppingCartQueryRes();
        log.info("res======{}",res);
        if(MapUtils.isNotEmpty(value)){
            map = value;
        }else {
            return res;
        }
        //订单总费用
        BigDecimal subTotalFee = BigDecimal.ZERO;
        //总运费
        BigDecimal subDeliveryFee = BigDecimal.ZERO;
        //可使用额度
        BigDecimal credit = BigDecimal.ZERO;
        //税收
        BigDecimal curTax = taxService.getCurTax();

        List<SupplierOrderVO> supplierOrderVOS = new ArrayList<>();
        //遍历购物车商品内容  封装底层商品数据
        List<VariantVO> variantVOList = conversionData(map);
        log.info("variantVOList====={}",variantVOList);
        if(variantVOList.size()>0){
            //避免循环查询sql;外层查询出全部的公司相关信息
            List<Long> companyList = new ArrayList<>();
            //根据卖家进行分组 ;sql 批量查询
            Map<Long, List<VariantVO>> collect = variantVOList.stream().collect(Collectors.groupingBy(VariantVO::getSupplierId));
            for(Map.Entry<Long,List<VariantVO>> entry:collect.entrySet()){
                Long companyId = entry.getKey();
                companyList.add(companyId);
            }
            List<CompanyInfoRes> listCompanyInfo = sysCompanyService.queryCompanyInfoBatch(companyList);

            for(Map.Entry<Long,List<VariantVO>> entry:collect.entrySet()){
                Long key = entry.getKey();
                List<VariantVO> value1 = entry.getValue();
                SupplierOrderVO supplierOrderVO = new SupplierOrderVO();
                BigDecimal totalFee = BigDecimal.ZERO;
                BigDecimal totalOrginalFee = BigDecimal.ZERO;
                CompanyInfoRes companyInfoRes = new CompanyInfoRes();
                for(CompanyInfoRes info :listCompanyInfo){
                    if(key.equals(info.getCompanyId())){
                        companyInfoRes = info;
                    }
                }
                supplierOrderVO.setVariants(value1);
                if(companyInfoRes==null){
                    continue;
                }
                supplierOrderVO.setSupplierCode(companyInfoRes.getInviteCode());
                if(value1!=null&&value1.size()>0){
                    for(VariantVO variantVO:value1){
                        BigDecimal num = BigDecimal.valueOf(variantVO.getQuantity());
                        //分别计算
                        totalFee = totalFee.add(variantVO.getSubFee());
                        totalOrginalFee = totalOrginalFee.add(variantVO.getOriginalPrice().multiply(num));
                    }
                    //获取公司包邮的最低金额
                    if(totalOrginalFee.compareTo(companyInfoRes.getDeliveryMoq()) == 1){
                        supplierOrderVO.setDeliveryFee(BigDecimal.ZERO);
                    }else{
                        supplierOrderVO.setDeliveryFee(companyInfoRes.getDeliveryCharge());
                        subDeliveryFee = subDeliveryFee.add(companyInfoRes.getDeliveryCharge());
                    }
                    //运费税费总价是分开的；方便计算
                    BigDecimal taxFee = (totalFee.add(companyInfoRes.getDeliveryCharge())).multiply(curTax);
                    subTotalFee = subTotalFee.add(totalFee);
                    supplierOrderVO.setTaxFee(taxFee);
                    supplierOrderVO.setTotalFee(totalFee);
                    supplierOrderVO.setSupplierId(key);
                    supplierOrderVOS.add(supplierOrderVO);
                }
            }
        }

        //商品总价加上运费加上商品的总税收加上运费的总税收 进行算法得到最终购物车总价
        BigDecimal allNeedCountTax = subTotalFee.add(subDeliveryFee);
        BigDecimal taxFee = allNeedCountTax.multiply(curTax);
        //商品总价
        String     roundByPenny = NumberUtils.getRoundByPenny(subTotalFee);
        BigDecimal allprice = new BigDecimal(roundByPenny);

        res.setSubTotalFee(allprice);
        res.setCredit(credit);
        res.setSubAdjustment(allprice.subtract(subTotalFee));  //调整的费用
        res.setSubDeliveryFee(subDeliveryFee);
        res.setSubTaxFee(taxFee);
        res.setSupplierOrders(supplierOrderVOS);
        return res;
    }

    @Override
    public List<VariantVO> queryVariantFromCart() {
        String cartKey = ShoppingCartUtils.getCurShoppingCartKey();
        Map redisCartMap = (Map) redisUtil.get(cartKey);
        List<VariantVO> listVariant = new ArrayList<>();
        if(MapUtils.isNotEmpty(redisCartMap)){
            //遍历购物车商品内容  封装底层商品数据
            listVariant = conversionData(redisCartMap);
            return listVariant;
        }else {
            return listVariant;
        }
    }

    /**
     * @description: 转化购物车商品
     * @author kyyang
     * @date 2021/6/3 23:09
     * @version 1.0
     */
    private List<VariantVO> conversionData(Map<String, Integer> map) {
        List<VariantVO> variantVOList = new ArrayList<>();
        SysADeduct curDeduct = sysADeductService.getCurDeduct();
        for(Map.Entry<String,Integer> entry :map.entrySet() ) {
            String  variantId = entry.getKey();
            Integer quantity  = entry.getValue();
            //获取变体
            SysProductVariantQueryCartRes sysProductVariant = sysProductVariantService.getSysProductVariant(Long.valueOf(variantId));
            if (sysProductVariant == null) {
                continue;
            }
            //调整售价：加系统提成
            BigDecimal beforePrice = sysProductVariant.getPrice();
            BigDecimal beforeSellPrice = sysProductVariant.getSellPrice();
            sysProductVariant.changePrice(curDeduct);
            VariantVO variantVO = new VariantVO();
            variantVO.setOriginalPrice(beforePrice);
            variantVO.setOriginalSellPrice(beforeSellPrice);
            BeanUtils.copyProperties(sysProductVariant,variantVO);
            variantVO.setQuantity(Long.valueOf(quantity));
            variantVO.setPicUrl(sysProductVariant.getPicUrl());
            //设置总额：
            BigDecimal num = BigDecimal.valueOf(quantity);
            BigDecimal subFee = sysProductVariant.getSellPrice()==null? sysProductVariant.getPrice().multiply(num):sysProductVariant.getSellPrice().multiply(num);
            variantVO.setSubFee(subFee);
            //查询 sku 详情
            SysProductVariantSku sysProductVariantSku = sysProductVariantSkuService.getSkuByVariantId(Long.valueOf(variantId));
            if (sysProductVariantSku != null) {
                variantVO.setUom(sysProductVariantSku.getUom());
                variantVO.setMoq(sysProductVariantSku.getMoq());
            }
            variantVOList.add(variantVO);
        }
        log.info("variantVOList===={}",variantVOList);
        return variantVOList;
    }

    @Override
    public void delProduct2CartByOrder(List<ProductCartReq> list) {
        String cartKey = ShoppingCartUtils.getCurShoppingCartKey();
        Map value = (Map) redisUtil.get(cartKey);
        Map<String,Integer> map = new HashMap<>();
        if(MapUtils.isNotEmpty(value)){
            map = value;
        }else {
            return ;
        }
        if(CollectionUtils.isNotEmpty(list)){
            for(ProductCartReq p:list){
                map.remove(p.getVariantId());
            }
        }
    }

    public static void main(String[] args) {
        Map<String, String> map = new HashMap<String, String>();
        map.put("01", "qwe");
        map.put("02", "asd");
        map.put("03", "zxc");
        // 通过entrySet()方法将map集合中的映射关系取出（这个关系就是Map.Entry类型）
        Set<Map.Entry<String, String>> entrySet = map.entrySet();
        // 将关系集合entryset进行迭代，存放到迭代器中
        Iterator<Map.Entry<String, String>> it2 = entrySet.iterator();
        while (it2.hasNext()) {
            // 获取Map.Entry关系对象me
            Map.Entry<String, String> me = it2.next();
            // 通过关系对像获取key
            String key2 = me.getKey();
            // 通过关系对像获取value
            String value2 = me.getValue();
            System.out.println("key:" + key2 + "-->value:" + value2);
        }
    }
    }